﻿using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using NLog;
using VIP.Infrastructure.Notice;
using Microsoft.Extensions.Configuration;

namespace WebApplication.Middlewares
{
    public class ResponseTimeMiddleware
    {
        // Name of the Response Header, Custom Headers starts with "X-"  
        private const string RESPONSE_HEADER_RESPONSE_TIME = "X-Response-Time-ms";
        // Handle to the next Middleware in the pipeline  
        private readonly RequestDelegate _next;
        NLog.ILogger _logger;
        IProgrammerNotice _noticer;
        IConfiguration _configuration;
        public ResponseTimeMiddleware(RequestDelegate next, NLog.ILogger logger, IProgrammerNotice noticer, IConfiguration configuration)
        {
            _next = next;
            _logger = logger;
            _noticer = noticer;
            _configuration = configuration;
        }
        public Task InvokeAsync(HttpContext context)
        {

            // Start the Timer using Stopwatch  
            var watch = new Stopwatch();
            watch.Start();
            context.Response.OnStarting(() =>
            {
                // Stop the timer information and calculate the time   
                watch.Stop();
                var responseTimeForCompleteRequest = watch.ElapsedMilliseconds;
                // Add the Response time information in the Response headers.   
                context.Response.Headers[RESPONSE_HEADER_RESPONSE_TIME] = responseTimeForCompleteRequest.ToString();

                var timeOut = _configuration.GetValue<int>("timeout");

                if (responseTimeForCompleteRequest > timeOut)
                {
                    var url = context.Request.Path.Value;
                    _noticer.Notice($"接口({url})响应时间超过了{timeOut}ms，实际响应时长（ms)：{responseTimeForCompleteRequest}");
                }
                return Task.CompletedTask;
            });
            // Call the next delegate/middleware in the pipeline   
            return this._next(context);
        }
    }
}
